package me.ahoukuse.capturedemov1;

import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

public class NetworkThreadUDP extends NetworkThread {
    private String server = "localhost";
    private int port = 2333;
    private DatagramSocket udpSocket;
    private final Deque<byte[]> dataQueue = new ArrayDeque<>();
    private int packetId = 0;
    private int maxPacketDataLength = 65000;
    private void open() throws IOException {
        udpSocket = new DatagramSocket(2333);
        udpSocket.connect(Inet4Address.getByName(server), port);
        Log.d("Debug", "open: UDP");
    }

    public NetworkThreadUDP(String server) {
        this.server = server;
    }
    public NetworkThreadUDP(String server, int size) {
        this.server = server;
        size = Math.min(60, size);
        maxPacketDataLength = size * 1024;
    }
    public NetworkThreadUDP() {

    }


    @Override
    public void addData(byte[] data) {
        synchronized (dataQueue) {
            dataQueue.addLast(data);
            dataQueue.notify();
        }
    }
    private void socketClose() {
        if (udpSocket != null) {
            udpSocket.disconnect();
            udpSocket.close();
            Log.d("Debug", "Socket closed");
        }
    }
    private void send() throws IOException, InterruptedException {
        byte[] rawData;
        synchronized (dataQueue) {
            while (dataQueue.isEmpty()) {
                dataQueue.wait();
            }
            rawData = dataQueue.pop();
        }
        //特殊意义
        if (rawData.length == 0)
            return;

        int offset = 0;

        if (rawData.length > maxPacketDataLength) {
            while (offset < rawData.length) {
                int bias = Math.min(maxPacketDataLength, rawData.length - offset);
                byte[] data = Arrays.copyOfRange(rawData, offset, offset+bias);
                Packet packet = new Packet();
                packet.setData(data);
                packet.setTotalLength(rawData.length);
                packet.setOffset(offset);
                packet.setDataLength(data.length);
                packet.setPacket_id(packetId);
                offset += bias;
                DatagramPacket datagramPacket = new DatagramPacket(packet.getBytes(),packet.getPacketLength(), Inet4Address.getByName(server),2333);
                udpSocket.send(datagramPacket);
            }
        } else {
            Packet packet = new Packet();
            packet.setData(rawData);
            packet.setOffset(0);
            packet.setPacket_id(packetId);
            DatagramPacket datagramPacket = new DatagramPacket(packet.getBytes(),packet.getPacketLength(), Inet4Address.getByName(server),2333);
            udpSocket.send(datagramPacket);
        }
        packetId++;
    }

    @Override
    public void run() {
        try {
            open();
            if (udpSocket != null) {
                while (!isExit) {
                    send();
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            socketClose();
            Log.d("Debug", "NetworkThreadUDP exit");
        }
    }
}
